package cn.realm;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

/**
 * Create by yster@foxmail.com 2018-05-12 05:59:16
**/
public class CustomRealm extends AuthorizingRealm {
	Map<String, String> userMap = new HashMap<>();
	//模拟数据库或缓存的数据
	{
//		Md5Hash md5 = new Md5Hash("123456");	//加密
		Md5Hash md5 = new Md5Hash("123456","Mark");//加盐
		userMap.put("Mark", md5.toString());
//		userMap.put("Mark", "123456");
		super.setName("customRealm");
	}
	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String username = (String) principals.getPrimaryPrincipal();
		// 从数据库或者缓存中获得角色数据
		Set<String> roles = getRolesByUserName(username);
		Set<String> permissions = getPermissionsByUserName(username);
		
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		simpleAuthorizationInfo.setStringPermissions(permissions);
		simpleAuthorizationInfo.setRoles(roles);
		
		return simpleAuthorizationInfo;
	}

	private Set<String> getPermissionsByUserName(String username) {
		Set<String> sets = new HashSet<>();
		sets.add("user:delete");
		sets.add("user:add");
		return sets;
	}

	private Set<String> getRolesByUserName(String username) {
		Set<String> sets = new HashSet<>();
		sets.add("admin");
		sets.add("user");
		return sets;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 1.从主体传过来的认证信息中，获得用户名
		String username = (String) token.getPrincipal();
		
		// 2.通过用户名到数据库中获取凭证
		String password = getPasswordByUsername(username);
		if(password == null) {
			return null;
		}
		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo("Mark", password, "customRealm");
		//加盐
		simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("Mark"));
		return simpleAuthenticationInfo;
	}

	private String getPasswordByUsername(String username) {
		return userMap.get(username);
	}

}
